Amazon DynamoDB独自のJSONデータ型「データ型記述子」についてまとめてみた
Amazon DynamoDBのデータの型が通常のJSONではない?
おのやんです。
みなさん、Amazon DynamoDB(以下、DynamoDB)に保存されているデータのJSON形式が独特なものになっていると思ったことはありませんか?私はあります。
DynamoDBに保存されているデータをJSONで表示しようとしたとき、「DynamoDB JSON の表示」のトグルがオンになっている状態で見て、通常のJSONとは違うデータ型で保存されていることに気づくと思います。
このデータ型は、DynamoDBの内部で使用される独自のものとなっています。最初見た時は戸惑いましたが、データ形式さえ押さえてしまえばなんてことはないデータなので、今回はDynamoDBのJSONデータ型についてまとめたいと思います。
データ型記述子
DynamoDBでは、JSONのデータを独自の形式で保存しており、この形式のことをデータ型記述子と呼びます
データ型記述子は、各属性を解釈する方法を DynamoDB に伝えるトークンです。
DynamoDBでデータを扱うときは、通常のJSONデータがデータ型記述子に変換されています。
例として、以下のJSONデータをDynamoDBに保存するケースを考えます。
{
"companyId": "COMP123",
"userId": "USER456",
"address": {
"city": "Anytown",
"state": "CA",
"street": "123 Main St",
"zipCode": "12345"
},
"age": 30,
"departments": [
"HR",
"Finance"
],
"email": "[email protected]",
"firstName": "John",
"isActive": true,
"lastLogin": "2023-05-15T14:30:00Z",
"lastName": "Doe",
"projects": [
"Project A",
"Project B",
"Project C"
],
"salary": 75000.5
}
DynamoDBに上記のJSONデータを保存する際は、データ型記述子に変換されます。以下の例を見てもらうとわかる通り、各値の部分にS
やN
などの文字が付与されているのがわかります。この記号によって、各値がDynamoDBでどう扱われるかが決定されます。
{
"companyId": {
"S": "COMP123"
},
"userId": {
"S": "USER456"
},
"address": {
"M": {
"city": {
"S": "Anytown"
},
"state": {
"S": "CA"
},
"street": {
"S": "123 Main St"
},
"zipCode": {
"S": "12345"
}
}
},
"age": {
"N": "30"
},
"departments": {
"L": [
{
"S": "HR"
},
{
"S": "Finance"
}
]
},
"email": {
"S": "[email protected]"
},
"firstName": {
"S": "John"
},
"isActive": {
"BOOL": true
},
"lastLogin": {
"S": "2023-05-15T14:30:00Z"
},
"lastName": {
"S": "Doe"
},
"projects": {
"L": [
{
"S": "Project A"
},
{
"S": "Project B"
},
{
"S": "Project C"
}
]
},
"salary": {
"N": "75000.5"
}
}
試しにマネジメントコンソール上から確認してみると、上記のデータはこのように解釈されていました。
DynamoDBのJSONでは、各記号にそれぞれ以下のような意味があります。
記号 | 意味 | サンプル値(DynamoDB JSON) | サンプル値(JSON) | 備考 |
---|---|---|---|---|
S | 文字列 | {"S": "COMP123"} | "COMP123" | |
N | 数値 | {"N": "30"} | 30 | |
B | バイナリ | {"B": "SGVsbG8="} | 変換不可 | リクエスト送信時にbase64への変換が必要 |
BOOL | ブール | {"BOOL": true} | true | |
NULL | Null | {"NULL": true} | null | |
M | マップ | {"M": {"city" :{"S": "Anytown"}}} | {"city": "Anytown"} | |
L | リスト | {"L": [{"S": "HR"}, {"S": "Finance"}]}` | `["HR", "Finance"] | |
SS | 文字列セット | {"SS": ["Red", "Green", "Blue"]}` | `["Red", "Green", "Blue"] | |
NS | 数値セット | {"NS": ["1.1", "2.2", "3.3"]} | [1.1, 2.2, 3.3] | |
BS | バイナリセット | {"BS": ["AAECAwQFBg==", "BwgJCgsMDQ==", "Dg8QERITFA=="]} | 変換不可 | リクエスト送信時にbase64への変換が必要 |
DynamoDBから取得してみた
こちらのデータを実際に取得すると、どのような形式のなるのか、検証してみました。
AWS CLIでデータを取得した場合、保存されているデータの形式(Items
の要素の形式)はDyanmoDB JSONになります。
$ aws dynamodb scan --table-name aws-test-dynamodb-table
{
"Items": [
{
"companyId": {
"S": "COMP123"
},
"lastName": {
"S": "Doe"
},
...
"age": {
"N": "30"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
boto3上でも取得してみます。サンプルとして、DynamoDBからテーブル内のデータを1件だけ取ってくる以下のコードを作成します。
import boto3
import json
def scan_and_display_dynamodb_item():
# DynamoDBクライアントを作成
dynamodb = boto3.client("dynamodb")
# テーブルをスキャン
response = dynamodb.scan(
TableName="aws-test-dynamodb-table",
Limit=1
)
# 結果を取得
items = response.get("Items",[])
print("Item found in the table:")
item = items[0]
print(item)
scan_and_display_dynamodb_item()
こちらを実行してみると、先ほどと同じようにDynamoDB JSONの形式で取得されることがわかります。
$ python3 sample.py
Item found in the table:
{'companyId': {'S': 'COMP123'}, 'lastName': {'S': 'Doe'}, 'projects': {'L': [{'S': 'Project A'}, {'S': 'Project B'}, {'S': 'Project C'}]}, 'salary': {'N': '75000.5'}, 'address': {'M': {'zipCode': {'S': '12345'}, 'state': {'S': 'CA'}, 'city': {'S': 'Anytown'}, 'street': {'S': '123 Main St'}}}, 'departments': {'L': [{'S': 'HR'}, {'S': 'Finance'}]}, 'email': {'S': '[email protected]'}, 'firstName': {'S': 'John'}, 'lastLogin': {'S': '2023-05-15T14:30:00Z'}, 'isActive': {'BOOL': True}, 'userId': {'S': 'USER456'}, 'binary': {'B': b'\x00\x00'}, 'age': {'N': '30'}}
実際にアプリケーション上でDynamoDBのデータを利用する場合は、JSON形式に型変換を行うことが多いです。JSONの型変換については、以下のブログにまとまっていますので、こちらを参考にしていただければと思います。
DynamoDBでは独自のJSONデータ形式を採用している
以上、DynamoDB上で扱っているJSONデータの形式についてまとめてみました。アプリケーション上でDynamoDBのデータを使用する場合は、ライブラリなどで型変換などのステップを踏むことが多いため、意外と大変だったりします。
DynamoDBのJSONデータについてわからなくなったら、本ブログを参考にしていただければと思います。では!